import * as insVue from 'vue'

import dayjs from 'dayjs'
import { cloneDeep } from 'lodash-es'
import { api, useAxiosResponse } from '@/api'
import { bwUtils as _bwUtils } from '@bitwit/utils'
import { useStorageStoreWithOut, onRefreshToken } from '@/store'
import ts, { ModuleKind, ModuleResolutionKind, ScriptTarget } from 'typescript'

import type { BwCallFunctionEngineOptionsModel } from './model'
import {
  SysProcAppPreviewFlowInput,
  SysProcAppPreviewFlowOutput,
  SysFunctionWebComponentInfo,
  SysProcInstanceAppGetInfoOutput,
  SysProcInstanceAppGetApplyTaskInput,
  SysProcInstanceAppGetCarbonTaskInput as SysCarbonTaskInput,
  SysProcInstanceAppGetApproveTaskInput as SysApproveTaskInput,
  SysProcInstanceAppGetApplyTaskInfoOutput as SysApplyTaskInfoOutput,
  SysProcInstanceAppGetCarbonTaskInfoOutput as SysCarbonTaskInfoOutput,
  SysProcInstanceAppGetApproveTaskInfoOutput as SysApproveTaskInfoOutput,
  SysProcInstanceAppDeliverApproveTaskInput as SysDeliverApproveTaskInput,
  SysProcInstanceAppAddSignApproveTaskInput as SysAddSignApproveTaskInput,
  SysProcInstanceAppTakebackAddSignApproveTaskInput as SysTakebackAddSignApproveTaskInput,
  BwPageResultOutputSysProcInstanceAppGetApplyTaskInfoOutput as SysApplyTaskPageOutput,
  BwPageResultOutputSysProcInstanceAppGetCarbonTaskInfoOutput as SysCarbonTaskPageOutput,
  BwPageResultOutputSysProcInstanceAppGetApproveTaskInfoOutput as SysApproveTaskPageOutput,
  SysTokenAppInfoOutput,
} from '@bitwit/tenantapi'

export function getTsToJs(code: string): string {
  code = ts.transpileModule(code, {
    compilerOptions: {
      target: ScriptTarget.ESNext,
      module: ModuleKind.ESNext,
      moduleResolution: ModuleResolutionKind.NodeNext,
      strict: true,
      noLib: false,
      noEmit: true,
      skipLibCheck: true,
      isolatedModules: true,
      forceConsistentCasingInFileNames: true,
      allowSyntheticDefaultImports: true,
      strictFunctionTypes: false,
      baseUrl: '.',
      allowJs: true,
      sourceMap: true,
      esModuleInterop: true,
      resolveJsonModule: true,
      noUnusedLocals: true,
      noUnusedParameters: true,
      experimentalDecorators: true,
      lib: ['dom', 'esnext'],
      noImplicitAny: false,
      removeComments: true,
    },
  }).outputText

  return code.replaceAll('\n', '') ?? ''
}

export function getInsBwUtils(options: Record<string, any>) {
  const bwUtils = {
    dayjs: dayjs,

    cloneDeep,
    flatArray: _bwUtils.flatArray,
    formatToDate: _bwUtils.formatToDate,
    /** 登录 获取token */
    getSysToken(params: {
      loginId: string
      password: string
      category: string
    }) {
      const { loginId, password, category = 'builtIn' } = params
      return new Promise((resolve, reject) => {
        api
          .apiSysTokenGetGet(loginId, password, category)
          .then((res) => {
            const resData = useAxiosResponse<SysTokenAppInfoOutput>(res)
            resolve(resData)
          })
          .catch((err) => {
            reject(err)
          })
      })
    },

    /** 获取地址数据 */
    getAddrSource() {
      return []
    },

    /** 设置Token */
    setToken(token: string) {
      const storageInfo = useStorageStoreWithOut()
      return storageInfo.setToken(token)
    },

    /** 获取Token */
    getToken() {
      const storageInfo = useStorageStoreWithOut()
      return storageInfo.getToken
    },

    /** 刷新token */
    onRefreshToken() {
      onRefreshToken()
    },

    /** 设置存储空间 -- 值 */
    setStorageInfo(key: string, value: any) {
      const storageInfo = useStorageStoreWithOut()
      storageInfo.setStorageInfo(key, value)
    },

    /** 获取存储空间信息  */
    getStorageInfo() {
      const storageInfo = useStorageStoreWithOut()
      return storageInfo.getStorageInfo
    },

    /** 获取存储空间信息  */
    getStorageValueToKey(key: string, defaultValue?: any) {
      const storageInfo = useStorageStoreWithOut()
      return storageInfo.getStorageValueToKey(key, defaultValue)
    },

    /** 函数引擎 调度 */
    callFunctionEngine(params: BwCallFunctionEngineOptionsModel): Promise<any> {
      return new Promise((resolve, reject) => {
        api
          .apiSysFunctionCallPost(params)
          .then((res) => {
            const resData = res.data
            resolve(resData)
          })
          .catch((err) => {
            reject(err)
          })
      })
    },

    /** 获取流程步骤预览流向 */
    getPreviewFolwProc(data: SysProcAppPreviewFlowInput) {
      return new Promise<any>((resolve, reject) => {
        if (data) {
          api.apiSysProcPreviewFlowPost(data).then((res) => {
            const resData = useAxiosResponse<SysProcAppPreviewFlowOutput>(res)
            console.log('获取流程步骤预览流向', resData)
            resolve(resData)
          })
        } else {
          reject()
        }
      })
    },

    /** 获取流程步骤申请页面信息 */
    getFlowPrcoStartPageInfo(procId: string): Promise<any> {
      return new Promise<any>((resolve, reject) => {
        if (procId) {
          api.apiSysProcInstanceGetStartPagePost({ procId }).then((res) => {
            const data: Record<string, any> = {}
            const resData = useAxiosResponse<SysFunctionWebComponentInfo>(res)
            try {
              const render = resData?.render
              if (render) {
                const renderInfo = render.replaceAll('\n', '')
                data.renderInfo = JSON.parse(renderInfo)
              }
            } catch (error) {
              data.renderInfo = null
            }

            resolve(data)
          })
        } else {
          reject()
        }
      })
    },

    /** 创建流程步骤 */
    createFlowPrco(
      procId: string,
      userId: string,
      userName: string,
      formData: Record<string, any>
    ): Promise<any> {
      return new Promise<any>((resolve, reject) => {
        if (procId) {
          api
            .apiSysProcInstanceCreatePost({
              procId,
              userId,
              userName,
              inputParams: formData,
            })
            .then((res) => {
              const resData = useAxiosResponse<string | null>(res)
              console.log('创建流程步骤', resData)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 获取流程步骤实例信息 */
    getFlowPrcoInsInfo(instanceId: string) {
      return new Promise<any>((resolve, reject) => {
        if (instanceId) {
          api.apiSysProcInstanceGetInfoPost({ instanceId }).then((res) => {
            const resData =
              useAxiosResponse<SysProcInstanceAppGetInfoOutput>(res)
            console.log('获取流程步骤实例信息', resData)
            resolve(resData)
          })
        } else {
          reject()
        }
      })
    },

    /** 启动流程步骤 (草稿项) */
    startFlowPrco(
      procId: string,
      insId: string,
      userId: string,
      userName: string
    ) {
      return new Promise<any>((resolve, reject) => {
        if (procId) {
          api
            .apiSysProcInstanceStartPost({
              procId,
              userId,
              userName,
              procInstanceId: insId,
            })
            .then((res) => {
              const resData = useAxiosResponse<void>(res)
              console.log('启动流程步骤', resData)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 获取发起任务列表 */
    getApplyTasks(data: SysProcInstanceAppGetApplyTaskInput) {
      return new Promise<any>((resolve, reject) => {
        if (data) {
          api.apiSysProcInstanceGetApplyTaskPost(data).then((res) => {
            const resData = useAxiosResponse<SysApplyTaskPageOutput>(res)
            resolve(resData?.rows)
          })
        } else {
          reject()
        }
      })
    },

    /** 获取发起任务信息 */
    getApplyTaskInfo(taskId: string) {
      return new Promise<any>((resolve, reject) => {
        if (taskId) {
          api.apiSysProcInstanceGetApplyTaskInfoPost({ taskId }).then((res) => {
            const resData = useAxiosResponse<SysApplyTaskInfoOutput>(res) ?? {}
            const pageInfo = resData?.pageComponent ?? {}
            try {
              const render = pageInfo.render
              if (render) {
                const renderInfo = render.replaceAll('\n', '')
                pageInfo.render = JSON.parse(renderInfo)
              } else {
                pageInfo.render = null
              }
            } catch (error) {
              pageInfo.render = null
            }

            resData.pageComponent = pageInfo
            resolve(resData)
          })
        } else {
          reject()
        }
      })
    },

    /** 提交发起任务信息 */
    submitApplyTask(taskId: string, userId: string, userName: string) {
      return new Promise<any>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceSubmitApplyTaskPost({ taskId, userId, userName })
            .then((res) => {
              const resData = useAxiosResponse<void>(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 删除发起任务信息 */
    delApplyTask(taskId: string, userId: string, userName: string) {
      return new Promise<any>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceDeleteApplyTaskPost({ taskId, userId, userName })
            .then((res) => {
              const resData = useAxiosResponse<void>(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 获取审批任务列表 */
    getApproveTasks(data: SysApproveTaskInput) {
      return new Promise<any>((resolve, reject) => {
        if (data) {
          api.apiSysProcInstanceGetApproveTaskPost(data).then((res) => {
            const resData = useAxiosResponse<SysApproveTaskPageOutput>(res)
            resolve(resData?.rows)
          })
        } else {
          reject()
        }
      })
    },

    /** 获取审批任务信息 */
    getApproveTaskInfo(taskId: string) {
      return new Promise<any>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceGetApproveTaskInfoPost({ taskId })
            .then((res) => {
              const resData = useAxiosResponse<SysApproveTaskInfoOutput>(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 同意审批任务信息 */
    agreeApproveTask(taskId: string, userId: string, userName: string) {
      return new Promise<any>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceAgreeApproveTaskPost({
              taskId,
              userId,
              userName,
            })
            .then((res) => {
              const resData = useAxiosResponse<void>(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 拒绝审批任务信息 */
    refuseApproveTask(taskId: string, userId: string, userName: string) {
      return new Promise<any>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceRefuseApproveTaskPost({
              taskId,
              userId,
              userName,
            })
            .then((res) => {
              const resData = useAxiosResponse<void>(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 获取可退回节点 */
    getCanBackNodes(insId: string, nodeId: string) {
      return new Promise<any>((resolve, reject) => {
        if (nodeId) {
          api
            .apiSysProcInstanceGetCanBackNodesPost({
              procInstanceId: insId,
              nodeId,
            })
            .then((res) => {
              const resData = useAxiosResponse<void>(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 退回审批任务 */
    backApproveTask(
      taskId: string,
      nodeIds: Array<string>,
      userId: string,
      userName: string
    ) {
      return new Promise<any>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceBackApproveTaskPost({
              taskId,
              userId,
              userName,
              targetNodeIds: nodeIds,
            })
            .then((res) => {
              const resData = useAxiosResponse(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 转交审批任务 */
    deliverApproveTask(data: SysDeliverApproveTaskInput) {
      return new Promise<any>((resolve, reject) => {
        if (data) {
          api
            .apiSysProcInstanceDeliverApproveTaskPost(data)
            .then((res) => {
              const resData = useAxiosResponse(res)
              resolve(resData)
            })
            .catch(() => reject())
        } else {
          reject()
        }
      })
    },

    /** 加签审批任务 */
    addSignApproveTask(data: SysAddSignApproveTaskInput) {
      return new Promise<any>((resolve, reject) => {
        if (data) {
          api
            .apiSysProcInstanceAddSignApproveTaskPost(data)
            .then((res) => {
              const resData = useAxiosResponse(res)
              resolve(resData)
            })
            .catch(() => reject())
        } else {
          reject()
        }
      })
    },

    /** 收回加签审批任务 */
    takebackAddSignApproveTask(data: SysTakebackAddSignApproveTaskInput) {
      return new Promise<any>((resolve, reject) => {
        if (data) {
          api
            .apiSysProcInstanceTakebackAddSignApproveTaskPost(data)
            .then((res) => {
              const resData = useAxiosResponse(res)
              resolve(resData)
            })
            .catch(() => reject())
        } else {
          reject()
        }
      })
    },

    /** 审批任务能否收回 */
    approveTaskCanTakeback(taskId: string) {
      return new Promise<boolean>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceApproveTaskCanTakebackPost({ taskId })
            .then((res) => {
              const resData = useAxiosResponse<boolean>(res)
              resolve(!!resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 获取抄送任务 */
    getCarbonTasks(data: SysCarbonTaskInput) {
      return new Promise<any>((resolve, reject) => {
        if (data) {
          api.apiSysProcInstanceGetCarbonTaskPost(data).then((res) => {
            const resData = useAxiosResponse<SysCarbonTaskPageOutput>(res)
            resolve(resData?.rows)
          })
        } else {
          reject()
        }
      })
    },

    /** 获取抄送任务信息 */
    getCarbonTaskInfo(taskId: string) {
      return new Promise<SysCarbonTaskInfoOutput | null>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceGetCarbonTaskInfoPost({ taskId })
            .then((res) => {
              const resData = useAxiosResponse<SysCarbonTaskInfoOutput>(res)
              resolve(resData ?? null)
            })
        } else {
          reject()
        }
      })
    },

    /** 阅读抄送任务 */
    readCarbonTask(taskId: string, userId: string, userName: string) {
      return new Promise<boolean>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceReadCarbonTaskPost({ taskId, userId, userName })
            .then((res) => {
              const resData = useAxiosResponse(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 取消阅读抄送任务 */
    unreadCarbonTask(taskId: string, userId: string, userName: string) {
      return new Promise<boolean>((resolve, reject) => {
        if (taskId) {
          api
            .apiSysProcInstanceUnReadCarbonTaskPost({
              taskId,
              userId,
              userName,
            })
            .then((res) => {
              const resData = useAxiosResponse(res)
              resolve(resData)
            })
        } else {
          reject()
        }
      })
    },

    /** 手动办结 */
    manualOver(insId: string, userId: string, userName: string) {
      return new Promise<boolean>((resolve, reject) => {
        if (insId) {
          api
            .apiSysProcInstanceManualOverPost({
              userId,
              userName,
              procInstanceId: insId,
            })
            .then((res) => {
              const resData = useAxiosResponse<boolean>(res)
              resolve(!!resData)
            })
            .catch(() => reject())
        } else {
          reject()
        }
      })
    },

    /** 中止 */
    terminate(insId: string, userId: string, userName: string) {
      return new Promise<boolean>((resolve, reject) => {
        if (insId) {
          api
            .apiSysProcInstanceTerminatePost({
              userId,
              userName,
              procInstanceId: insId,
            })
            .then((res) => {
              const resData = useAxiosResponse<boolean>(res)
              resolve(!!resData)
            })
            .catch(() => reject())
        } else {
        }
      })
    },

    /** 保存节点变量 */
    onSaveNodeVariable(
      insId: string,
      nodeId: string,
      userId: string,
      userName: string,
      formData: Record<string, any>
    ) {
      return new Promise<boolean>((resolve, reject) => {
        if (insId) {
          api
            .apiSysProcInstanceSaveNodeVariablePost({
              nodeId,
              userId,
              userName,
              procInstanceId: insId,
              variableData: formData,
            })
            .then((res) => {
              const resData = useAxiosResponse<boolean>(res)
              resolve(!!resData)
            })
            .catch(() => reject())
        } else {
          reject()
        }
      })
    },
  }
  return Object.assign(bwUtils, insVue, options)
}
